#include "scheduler/while_do_scheduler.h"
#include "../policy/policy_factory.h"
#include "../policy/behavior_tree/behavior_tree_while_do_policy.h"

namespace scheduler
{
WhileDoScheduler::WhileDoScheduler(const std::string &name)
    : AbstractScheduler(name)
{
    schedule_policy_ = policy::PolicyFactory<policy::BehaviorTreeWhileDoPolicy>::createPolicy(name);
}
WhileDoScheduler::~WhileDoScheduler() = default;

bool WhileDoScheduler::setWhileConditionTask(const task::AbstractTaskConstPtr &task)
{
    if (task->getTaskType() != task::TaskType::SYNC_REQUEST_TASK)
    {
        EASE_ERROR("while do scheduler condition must be request task");
        throw std::runtime_error("while do scheduler condition must be request task");
    }

    auto policy = dynamic_cast<policy::BehaviorTreeWhileDoPolicy *>(schedule_policy_.get());
    if (nullptr == policy)
    {
        throw std::runtime_error("while do scheduler policy case fail");
    }
    return policy->setWhileConditionTask(task);
}
bool WhileDoScheduler::setWhileConditionScheduler(const AbstractSchedulerConstPtr &scheduler)
{
    auto policy = dynamic_cast<policy::BehaviorTreeWhileDoPolicy *>(schedule_policy_.get());
    if (nullptr == policy)
    {
        throw std::runtime_error("while do scheduler policy case fail");
    }
    scheduler_vec_.push_back(scheduler);
    return policy->setWhileConditionPolicy(scheduler->getTaskPolicy());
}
bool WhileDoScheduler::setExecuteTask(const task::AbstractTaskConstPtr &task)
{
    auto policy = dynamic_cast<policy::BehaviorTreeWhileDoPolicy *>(schedule_policy_.get());
    if (nullptr == policy)
    {
        throw std::runtime_error("while do scheduler policy case fail");
    }
    return policy->setExecuteTask(task);
}
bool WhileDoScheduler::setExecuteScheduler(const AbstractSchedulerConstPtr &scheduler)
{
    auto policy = dynamic_cast<policy::BehaviorTreeWhileDoPolicy *>(schedule_policy_.get());
    if (nullptr == policy)
    {
        throw std::runtime_error("while do scheduler policy case fail");
    }
    scheduler_vec_.push_back(scheduler);
    return policy->setExecutePolicy(scheduler->getTaskPolicy());
}
void WhileDoScheduler::setEndCondition(task::TaskStatus status)
{
    auto *policy = dynamic_cast<policy::BehaviorTreeWhileDoPolicy *>(schedule_policy_.get());
    if (nullptr == policy)
    {
        throw std::runtime_error("while do scheduler case fail");
    }
    policy->setEndCondition(status);
}
bool WhileDoScheduler::appendTask(const task::AbstractTaskConstPtr &task)
{
    EASE_ERROR("while do scheduler cannot append task");
    throw std::runtime_error("while do scheduler cannot append task");
}
bool WhileDoScheduler::appendScheduler(const AbstractSchedulerConstPtr &scheduler)
{
    EASE_ERROR("while do scheduler cannot append scheduler");
    throw std::runtime_error("while do scheduler cannot append scheduler");
}
bool WhileDoScheduler::setTask(const task::AbstractTaskConstPtr &task)
{
    EASE_ERROR("while do scheduler cannot set task");
    throw std::runtime_error("while do scheduler cannot set task");
}
bool WhileDoScheduler::setScheduler(const AbstractSchedulerConstPtr &scheduler)
{
    EASE_ERROR("while do scheduler cannot set scheduler");
    throw std::runtime_error("while do scheduler cannot set scheduler");
}

}
